﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.Text;
using System.Xml.Schema;
using System.Qizx.Xdm;
using System.Collections;
using System.Qizx.Api;

namespace System.Xml.Schema {
    public static class XmlSchemaSetExtensions {
        public static XmlSchemaDatatype GetDataType(this XmlSchemaSet schemas, XmlSchemaElement schemaElement) {
            if (schemas == null || schemaElement == null) return null;
            if (schemaElement.SchemaTypeName != null && !schemaElement.SchemaTypeName.IsEmpty) {
                if (schemaElement.SchemaTypeName.Namespace == XmlSchema.Namespace) {
                    return XmlSchemaType.GetBuiltInSimpleType(schemaElement.SchemaTypeName).Datatype;
                }
                XmlSchemaObject obj = schemas.GlobalTypes[schemaElement.SchemaTypeName];
                XmlSchemaSimpleType simpleType = obj as XmlSchemaSimpleType;
                if (simpleType != null) {
                    if (simpleType.Datatype != null)
                        return simpleType.Datatype;
                }
                XmlSchemaComplexType complexType = obj as XmlSchemaComplexType;
                if (complexType != null) {
                    XmlSchemaSimpleContent sc = complexType.ContentModel as XmlSchemaSimpleContent;
                    if (sc != null) {
                        XmlSchemaSimpleContentExtension sce = sc.Content as XmlSchemaSimpleContentExtension;
                        if (sce != null) {
                            return GetDataType(schemas, sce.BaseTypeName);
                        }
                    }
                }
            }

            XmlSchemaType elementType = schemaElement.ElementSchemaType;
            if (elementType != null && elementType.BaseXmlSchemaType != null && elementType.BaseXmlSchemaType.QualifiedName != null) {
                return GetDataType(schemas, elementType.BaseXmlSchemaType.QualifiedName);
            }

            XmlSchemaType schemaType = schemaElement.SchemaType;
            if (schemaType != null) {
                if (schemaType.Datatype != null) return schemaType.Datatype;
            }
            //TODO XmlSchemaSet extensions
            return null;
        }

        public static KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype> GetAttributeDataType(this XmlSchemaSet schemaSet, XmlSchemaType schemaType, XmlQualifiedName attributeName) {
            XmlSchemaComplexType complexType = schemaType as XmlSchemaComplexType;
            if (complexType != null) {
                XmlSchemaComplexContent cc = complexType.ContentModel as XmlSchemaComplexContent;
                if (cc != null) {
                    XmlSchemaComplexContentExtension cce = cc.Content as XmlSchemaComplexContentExtension;
                    if (cce != null) {
                        foreach (XmlSchemaObject so in cce.Attributes) {
                            XmlSchemaAttribute attr = so as XmlSchemaAttribute;
                            if (attr != null && attr.QualifiedName.Equals(attributeName)) {
                                if (attr.SchemaTypeName != null && !attr.SchemaTypeName.IsEmpty) {
                                    XmlSchemaSimpleType simpleType = XmlSchemaType.GetBuiltInSimpleType(attr.SchemaTypeName);
                                    if (simpleType == null) {
                                        simpleType = schemaSet.GlobalTypes[attr.SchemaTypeName] as XmlSchemaSimpleType;
                                    }

                                    if (simpleType != null && simpleType.Datatype != null)
                                        return new KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype>(attr, simpleType.Datatype);
                                }
                            }
                        }
                    } else {
                        XmlSchemaComplexContentRestriction ccr = cc.Content as XmlSchemaComplexContentRestriction;
                        if (ccr != null) {
                            foreach (XmlSchemaObject so in ccr.Attributes) {
                                XmlSchemaAttribute attr = so as XmlSchemaAttribute;
                                if (attr != null && attr.QualifiedName.Equals(attributeName)) {
                                    if (attr.SchemaTypeName != null && !attr.SchemaTypeName.IsEmpty) {
                                        XmlSchemaSimpleType simpleType = XmlSchemaType.GetBuiltInSimpleType(attr.SchemaTypeName);
                                        if (simpleType == null) {
                                            simpleType = schemaSet.GlobalTypes[attr.SchemaTypeName] as XmlSchemaSimpleType;
                                        }

                                        if (simpleType != null && simpleType.Datatype != null)
                                            return new KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype>(attr, simpleType.Datatype);
                                    }
                                }
                            }
                        }
                    }
                }
                XmlSchemaSimpleContent sc = complexType.ContentModel as XmlSchemaSimpleContent;
                if (sc != null) {

                    XmlSchemaSimpleContentExtension sce = sc.Content as XmlSchemaSimpleContentExtension;
                    if (sce != null) {
                        foreach (XmlSchemaObject so in sce.Attributes) {
                            XmlSchemaAttribute attr = so as XmlSchemaAttribute;
                            if (attr != null && attr.QualifiedName.Equals(attributeName)) {
                                if (attr.SchemaTypeName != null && !attr.SchemaTypeName.IsEmpty) {
                                    XmlSchemaSimpleType simpleType = XmlSchemaType.GetBuiltInSimpleType(attr.SchemaTypeName);
                                    if (simpleType == null) {
                                        simpleType = schemaSet.GlobalTypes[attr.SchemaTypeName] as XmlSchemaSimpleType;
                                    }

                                    if (simpleType != null && simpleType.Datatype != null)
                                        return new KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype>(attr, simpleType.Datatype);
                                }
                            }
                        }
                    }
                }

                foreach (XmlSchemaAttribute attr in complexType.Attributes) {
                    if (attr.QualifiedName.Equals(attributeName)) {
                        if (attr.SchemaTypeName != null && !attr.SchemaTypeName.IsEmpty) {
                            XmlSchemaSimpleType simpleType = XmlSchemaType.GetBuiltInSimpleType(attr.SchemaTypeName);
                            if (simpleType == null) {
                                simpleType = schemaSet.GlobalTypes[attr.SchemaTypeName] as XmlSchemaSimpleType;
                            }

                            if (simpleType != null && simpleType.Datatype != null)
                                return new KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype>(attr, simpleType.Datatype);
                        }
                    }
                }
            }
            return new KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype>();
        }

        public static KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype> GetAttributeDataType(this XmlSchemaSet schemaSet, XmlNode attribute) {
            XmlQualifiedName parentName = new XmlQualifiedName(attribute.LocalName, attribute.NamespaceURI);
            if (!string.IsNullOrEmpty(attribute.NamespaceURI)) {
                ICollection schemas = schemaSet.Schemas(attribute.NamespaceURI);
                foreach (XmlSchema schema in schemas) {
                    XmlSchemaAttribute schemaAttribute = schema.Attributes[parentName] as XmlSchemaAttribute;
                    if (schemaAttribute != null) {
                        if (schemaAttribute.SchemaTypeName != null && !schemaAttribute.SchemaTypeName.IsEmpty) {
                            XmlSchemaSimpleType simpleType = XmlSchemaType.GetBuiltInSimpleType(schemaAttribute.SchemaTypeName);
                            if (simpleType == null) {
                                simpleType = schemaSet.GlobalTypes[schemaAttribute.SchemaTypeName] as XmlSchemaSimpleType;
                            }
                            if (simpleType.Datatype != null) {
                                return new KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype>(schemaAttribute, simpleType.Datatype);
                            }
                            break;
                        }

                    }
                }
            } else {
                XmlSchemaElement schemaElement = GetSchemaElement(schemaSet, attribute.ParentNode);
                if (schemaElement != null) {
                    if (schemaElement.ElementSchemaType != null) {
                        return schemaSet.GetAttributeDataType(schemaElement.ElementSchemaType, parentName);
                    }
                }
            }
            return new KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype>();
        }

        public static KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype> GetAttributeDataType(this XmlSchemaSet schemaSet, BasicNode attribute) {
            if (!string.IsNullOrEmpty(attribute.NamespaceURI)) {
                ICollection schemas = schemaSet.Schemas(attribute.NamespaceURI);
                foreach (XmlSchema schema in schemas) {
                    XmlSchemaAttribute schemaAttribute = schema.Attributes[attribute.NodeName] as XmlSchemaAttribute;
                    if (schemaAttribute != null) {
                        if (schemaAttribute.SchemaTypeName != null && !schemaAttribute.SchemaTypeName.IsEmpty) {
                            XmlSchemaSimpleType simpleType = XmlSchemaType.GetBuiltInSimpleType(schemaAttribute.SchemaTypeName);
                            if (simpleType == null) {
                                simpleType = schemaSet.GlobalTypes[schemaAttribute.SchemaTypeName] as XmlSchemaSimpleType;
                            }
                            if (simpleType.Datatype != null) {
                                return new KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype>(schemaAttribute, simpleType.Datatype);
                            }
                            break;
                        }

                    }
                }
            } else {
                XmlSchemaElement schemaElement = GetSchemaElement(schemaSet, attribute.ParentNode);
                if (schemaElement != null) {
                    if (schemaElement.ElementSchemaType != null) {
                        return schemaSet.GetAttributeDataType(schemaElement.ElementSchemaType, attribute.NodeName);
                    }
                }
            }
            return new KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype>();
        }


        public static XmlSchemaDatatype GetAttributeDataType(this XmlSchemaSet schemaSet, XmlSchemaAttribute schemaAttribute) {
            if (schemaAttribute != null) {
                if (schemaAttribute.SchemaTypeName != null && !schemaAttribute.SchemaTypeName.IsEmpty) {
                    XmlSchemaSimpleType simpleType = XmlSchemaType.GetBuiltInSimpleType(schemaAttribute.SchemaTypeName);
                    if (simpleType == null) {
                        simpleType = schemaSet.GlobalTypes[schemaAttribute.SchemaTypeName] as XmlSchemaSimpleType;
                    }
                    if (simpleType.Datatype != null) {
                        return simpleType.Datatype;
                    }
                }
            }
            return null;
        }

        public static KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype> GetAttributeDataType(this XmlSchemaSet schemaSet, XmlAttribute attribute) {
            XmlQualifiedName attrName = new XmlQualifiedName(attribute.LocalName,attribute.NamespaceURI);
            if (!string.IsNullOrEmpty(attribute.NamespaceURI)) {
                ICollection schemas = schemaSet.Schemas(attribute.NamespaceURI);
                foreach (XmlSchema schema in schemas) {
                    XmlSchemaAttribute schemaAttribute = schema.Attributes[attrName] as XmlSchemaAttribute;
                    if (schemaAttribute != null) {
                        if (schemaAttribute.SchemaTypeName != null && !schemaAttribute.SchemaTypeName.IsEmpty) {
                            XmlSchemaSimpleType simpleType = XmlSchemaType.GetBuiltInSimpleType(schemaAttribute.SchemaTypeName);
                            if (simpleType == null) {
                                simpleType = schemaSet.GlobalTypes[schemaAttribute.SchemaTypeName] as XmlSchemaSimpleType;
                            }
                            if (simpleType.Datatype != null) {
                                return new KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype>(schemaAttribute, simpleType.Datatype);
                            }
                            break;
                        }

                    }
                }
            } else {
                XmlSchemaElement schemaElement = GetSchemaElement(schemaSet, attribute.ParentNode);
                if (schemaElement != null) {
                    if (schemaElement.ElementSchemaType != null) {
                        return schemaSet.GetAttributeDataType(schemaElement.ElementSchemaType, attrName);
                    }
                }
            }
            return new KeyValuePair<XmlSchemaAttribute, XmlSchemaDatatype>();
        }

        public static XmlSchemaElement GetSchemaElement(this XmlSchemaSet schemaSet, Node element) {
            ICollection schemas = schemaSet.Schemas(element.NamespaceURI);
            foreach (XmlSchema schema in schemas) {
                XmlSchemaObject schemaObj = schema.Elements[element.NodeName];
                if (schemaObj != null) {
                    return schemaObj as XmlSchemaElement;
                }
            }
            if (element.ParentNode != null && element.ParentNode.NodeType != XdmNodeType.Document) {
                Stack<Node> nodeAxis = new Stack<Node>();
                nodeAxis.Push(element);
                return GetSchemaElement(schemaSet, element.ParentNode, nodeAxis);
            }
            return null;
        }

        public static XmlSchemaElement GetSchemaElement(this XmlSchemaSet schemaSet, XmlNode element) {
            XmlQualifiedName qname = new XmlQualifiedName(element.LocalName, element.NamespaceURI);
            ICollection schemas = schemaSet.Schemas(element.NamespaceURI);
            foreach (XmlSchema schema in schemas) {
                XmlSchemaObject schemaObj = schema.Elements[qname];
                if (schemaObj != null) {
                    return schemaObj as XmlSchemaElement;
                }
            }
            if (element.ParentNode != null && element.ParentNode.NodeType != XmlNodeType.Document) {
                Stack<XmlNode> nodeAxis = new Stack<XmlNode>();
                nodeAxis.Push(element);
                return GetSchemaElement(schemaSet, element.ParentNode, nodeAxis);
            }
            return null;
        }

        private static XmlSchemaElement GetSchemaElement(this XmlSchemaSet schemaSet, XmlNode parent, Stack<XmlNode> nodeAxis) {
            ICollection schemas = schemaSet.Schemas(parent.NamespaceURI);
            XmlQualifiedName parentName = new XmlQualifiedName(parent.LocalName, parent.NamespaceURI);
            foreach (XmlSchema schema in schemas) {
                XmlSchemaObject schemaObj = schema.Elements[parentName];
                if (schemaObj != null) {
                    XmlSchemaElement schemaElement = schemaObj as XmlSchemaElement;
                    if (schemaElement != null) {
                        return GetSchemaElement(schemaSet, schemaElement, nodeAxis);
                    }
                    return null;
                }
            }
            if (parent.ParentNode != null && parent.ParentNode.NodeType != XmlNodeType.Document) {
                nodeAxis.Push(parent);
                return GetSchemaElement(schemaSet, parent.ParentNode, nodeAxis);
            }
            return null;
        }

        private static XmlSchemaElement GetSchemaElement(this XmlSchemaSet schemaSet, Node parent, Stack<Node> nodeAxis) {
            ICollection schemas = schemaSet.Schemas(parent.NamespaceURI);
            foreach (XmlSchema schema in schemas) {
                XmlSchemaObject schemaObj = schema.Elements[parent.NodeName];
                if (schemaObj != null) {
                    XmlSchemaElement schemaElement = schemaObj as XmlSchemaElement;
                    if (schemaElement != null) {
                        return GetSchemaElement(schemaSet, schemaElement, nodeAxis);
                    }
                    return null;
                }
            }
            if (parent.ParentNode != null && parent.ParentNode.NodeType != XdmNodeType.Document) {
                nodeAxis.Push(parent);
                return GetSchemaElement(schemaSet, parent.ParentNode, nodeAxis);
            }
            return null;
        }

        internal static XmlSchemaElement GetSchemaElement(this XmlSchemaSet schemaSet, XmlSchemaElement parent, Stack<Node> nodeAxis) {
            if (parent.RefName != null && !parent.RefName.IsEmpty) {
                XmlSchemaElement element = schemaSet.GlobalElements[parent.RefName] as XmlSchemaElement;
                if (element != null) {
                    return GetSchemaElement(schemaSet, element, nodeAxis);
                }
            }

            if (nodeAxis.Count == 0) return parent;

            XmlSchemaComplexType complexType = parent.SchemaType as XmlSchemaComplexType;
            if (complexType != null) {
                return GetSchemaElement(schemaSet, complexType, nodeAxis);
            }
            if (parent.SchemaTypeName != null && !parent.SchemaTypeName.IsEmpty) {
                XmlSchemaObject schemaType = schemaSet.GlobalTypes[parent.SchemaTypeName];
                if (schemaType != null) {
                    complexType = schemaType as XmlSchemaComplexType;
                    if (complexType != null) {
                        return GetSchemaElement(schemaSet, complexType, nodeAxis);
                    }
                }
            }
            return null;
        }

        internal static XmlSchemaElement GetSchemaElement(this XmlSchemaSet schemaSet, XmlSchemaElement parent, Stack<XmlNode> nodeAxis) {
            if (parent.RefName != null && !parent.RefName.IsEmpty) {
                XmlSchemaElement element = schemaSet.GlobalElements[parent.RefName] as XmlSchemaElement;
                if (element != null) {
                    return GetSchemaElement(schemaSet, element, nodeAxis);
                }
            }

            if (nodeAxis.Count == 0) return parent;

            XmlSchemaComplexType complexType = parent.SchemaType as XmlSchemaComplexType;
            if (complexType != null) {
                return GetSchemaElement(schemaSet, complexType, nodeAxis);
            }
            if (parent.SchemaTypeName != null && !parent.SchemaTypeName.IsEmpty) {
                XmlSchemaObject schemaType = schemaSet.GlobalTypes[parent.SchemaTypeName];
                if (schemaType != null) {
                    complexType = schemaType as XmlSchemaComplexType;
                    if (complexType != null) {
                        return GetSchemaElement(schemaSet, complexType, nodeAxis);
                    }
                }
            }
            return null;
        }

        internal static XmlSchemaElement GetSchemaElement(this XmlSchemaSet schemaSet, XmlSchemaComplexType parent, Stack<Node> nodeAxis) {
            if (nodeAxis.Count == 0) return null;

            Node childNode = nodeAxis.Peek();
            QName childName = childNode.NodeName;

            XmlSchemaComplexContent complexContent = parent.ContentModel as XmlSchemaComplexContent;
            if (complexContent != null) {
                XmlSchemaComplexContentRestriction res = complexContent.Content as XmlSchemaComplexContentRestriction;
                if (res != null) {
                    if (res.Particle != null) {
                        return GetSchemaElement(schemaSet, res.Particle, nodeAxis);
                    }
                } else {
                    XmlSchemaComplexContentExtension ext = complexContent.Content as XmlSchemaComplexContentExtension;
                    if (ext != null) {
                        if (ext.Particle != null) {
                            return GetSchemaElement(schemaSet, ext.Particle, nodeAxis);
                        }
                    }
                }
            }

            if (parent.ContentTypeParticle != null) {
                return GetSchemaElement(schemaSet, parent.ContentTypeParticle, nodeAxis);
            }

            if (parent.Particle != null) {
                return GetSchemaElement(schemaSet, parent.Particle, nodeAxis);
            }

            return null;
        }

        internal static XmlSchemaElement GetSchemaElement(this XmlSchemaSet schemaSet, XmlSchemaComplexType parent, Stack<XmlNode> nodeAxis) {
            if (nodeAxis.Count == 0) return null;

            XmlNode childNode = nodeAxis.Peek();
            XmlQualifiedName childName = new XmlQualifiedName(childNode.LocalName, childNode.NamespaceURI);

            XmlSchemaComplexContent complexContent = parent.ContentModel as XmlSchemaComplexContent;
            if (complexContent != null) {
                XmlSchemaComplexContentRestriction res = complexContent.Content as XmlSchemaComplexContentRestriction;
                if (res != null) {
                    if (res.Particle != null) {
                        return GetSchemaElement(schemaSet, res.Particle, nodeAxis);
                    }
                } else {
                    XmlSchemaComplexContentExtension ext = complexContent.Content as XmlSchemaComplexContentExtension;
                    if (ext != null) {
                        if (ext.Particle != null) {
                            return GetSchemaElement(schemaSet, res.Particle, nodeAxis);
                        }
                    }
                }
            }

            if (parent.ContentTypeParticle != null) {
                return GetSchemaElement(schemaSet, parent.ContentTypeParticle, nodeAxis);
            }

            if (parent.Particle != null) {
                return GetSchemaElement(schemaSet, parent.Particle, nodeAxis);
            }

            return null;
        }

        internal static XmlSchemaElement GetSchemaElement(this XmlSchemaSet schemaSet, XmlSchemaParticle parent, Stack<Node> nodeAxis) {
            if (nodeAxis.Count == 0) return null;
            QName childName = nodeAxis.Peek().NodeName;

            XmlSchemaGroupBase gbase = parent as XmlSchemaGroupBase;
            if (gbase != null) {
                XmlSchemaElement se2 = GetSchemaElement(schemaSet, gbase, nodeAxis);
                if (se2 != null)
                    return se2;
            }

            XmlSchemaGroupRef groupRef2 = parent as XmlSchemaGroupRef;
            if (groupRef2 != null) {
                foreach (XmlSchema schema in schemaSet.Schemas(groupRef2.RefName.Namespace)) {
                    XmlSchemaGroup group = schema.Groups[groupRef2.RefName] as XmlSchemaGroup;
                    if (group != null) {
                        XmlSchemaElement se3 = GetSchemaElement(schemaSet, group.Particle, nodeAxis);
                        if (se3 != null)
                            return se3;
                    }
                }
            }

            XmlSchemaElement se4 = parent as XmlSchemaElement;
            if (se4 != null) {
                if (se4.QualifiedName.Equals(childName)) {
                    nodeAxis.Pop();
                    return GetSchemaElement(schemaSet, se4, nodeAxis);
                }
            }

            return null;
        }

        internal static XmlSchemaElement GetSchemaElement(this XmlSchemaSet schemaSet, XmlSchemaParticle parent, Stack<XmlNode> nodeAxis) {
            if (nodeAxis.Count == 0) return null;
            XmlNode peekNode = nodeAxis.Peek();
            XmlQualifiedName childName = new XmlQualifiedName(peekNode.LocalName, peekNode.NamespaceURI);

            XmlSchemaGroupBase gbase = parent as XmlSchemaGroupBase;
            if (gbase != null) {
                XmlSchemaElement se2 = GetSchemaElement(schemaSet, gbase, nodeAxis);
                if (se2 != null)
                    return se2;
            }

            XmlSchemaGroupRef groupRef2 = parent as XmlSchemaGroupRef;
            if (groupRef2 != null) {
                foreach (XmlSchema schema in schemaSet.Schemas(groupRef2.RefName.Namespace)) {
                    XmlSchemaGroup group = schema.Groups[groupRef2.RefName] as XmlSchemaGroup;
                    if (group != null) {
                        XmlSchemaElement se3 = GetSchemaElement(schemaSet, group.Particle, nodeAxis);
                        if (se3 != null)
                            return se3;
                    }
                }
            }

            XmlSchemaElement se4 = parent as XmlSchemaElement;
            if (se4 != null) {
                if (se4.QualifiedName.Equals(childName)) {
                    nodeAxis.Pop();
                    return GetSchemaElement(schemaSet, se4, nodeAxis);
                }
            }

            return null;
        }

        internal static XmlSchemaElement GetSchemaElement(this XmlSchemaSet schemaSet, XmlSchemaGroupBase gbase, Stack<Node> nodeAxis) {
            if (nodeAxis.Count == 0) return null;
            QName childName = nodeAxis.Peek().NodeName;

            foreach (XmlSchemaObject obj in gbase.Items) {
                XmlSchemaElement element = obj as XmlSchemaElement;
                if (element != null) {
                    if (element.QualifiedName.Equals(childName)) {
                        nodeAxis.Pop();
                        return GetSchemaElement(schemaSet, element, nodeAxis);
                    }
                } else {
                    XmlSchemaGroupBase gbase2 = obj as XmlSchemaGroupBase;
                    if (gbase2 != null) {
                        XmlSchemaElement se2 = GetSchemaElement(schemaSet, gbase2, nodeAxis);
                        if (se2 != null)
                            return se2;
                    } else {
                        XmlSchemaGroupRef groupRef = obj as XmlSchemaGroupRef;
                        if (groupRef != null) {
                            foreach (XmlSchema schema in schemaSet.Schemas(groupRef.RefName.Namespace)) {
                                XmlSchemaGroup group = schema.Groups[groupRef.RefName] as XmlSchemaGroup;
                                if (group != null) {
                                    XmlSchemaElement se3 = GetSchemaElement(schemaSet, group.Particle, nodeAxis);
                                    if (se3 != null)
                                        return se3;
                                }
                            }
                        }
                    }
                }
            }

            return null;
        }

        public static XmlSchemaDatatype GetDataType(this XmlSchemaSet schemas, XmlQualifiedName typeName) {
            if (typeName.Namespace == "http://www.w3.org/2001/XMLSchema") {
                XmlSchemaSimpleType simpleType2 = XmlSchemaType.GetBuiltInSimpleType(typeName);
                return simpleType2 == null ? null : simpleType2.Datatype;
            }
            XmlSchemaObject obj = schemas.GlobalTypes[typeName];
            XmlSchemaSimpleType simpleType = obj as XmlSchemaSimpleType;
            if (simpleType != null) {
                if (simpleType.Datatype != null)
                    return simpleType.Datatype;
            }
            XmlSchemaComplexType complexType = obj as XmlSchemaComplexType;
            if (complexType != null) {
                XmlSchemaSimpleContent sc = complexType.ContentModel as XmlSchemaSimpleContent;
                if (sc != null) {
                    XmlSchemaSimpleContentExtension sce = sc.Content as XmlSchemaSimpleContentExtension;
                    if (sce != null) {
                        return GetDataType(schemas, sce.BaseTypeName);
                    }
                }
            }
            return null;
        }
    }
}
